﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json;

namespace HigLabo.Net.Twitter
{
    public partial class TwitterClient
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="userID"></param>
        /// <param name="callback"></param>
        public void GetFollowers(Int64 userID, Action<Friends> callback)
        {
            var cm = new GetFriendsCommand();
            cm.UserID = userID;
            this.GetFollowers(cm, callback);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="command"></param>
        /// <param name="callback"></param>
        public void GetFollowers(GetFriendsCommand command, Action<Friends> callback)
        {
            this.GetResultText(TwitterApiUrl.Version1_1.Friends.GetFollowersUrl, command
                , json => callback(new Friends(json)));
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="userID"></param>
        /// <param name="callback"></param>
        public void GetFriends(Int64 userID, Action<Friends> callback)
        {
            var cm = new GetFriendsCommand();
            cm.UserID = userID;
            this.GetFriends(cm, callback);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="command"></param>
        /// <param name="callback"></param>
        public void GetFriends(GetFriendsCommand command, Action<Friends> callback)
        {
            this.GetResultText(TwitterApiUrl.Version1_1.Friends.GetFriendsUrl, command
                , json => callback(new Friends(json)));
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="callback"></param>
        public void GetIncomingFriends(Action<Friends> callback)
        {
            this.GetIncomingFriends(null as GetPendingFollowFriendsCommand, callback);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="command"></param>
        /// <param name="callback"></param>
        public void GetIncomingFriends(GetPendingFollowFriendsCommand command, Action<Friends> callback)
        {
            this.GetResultText(TwitterApiUrl.Version1_1.Friends.GetIncomingUrl, command
                , json => callback(new Friends(json)));
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="callback"></param>
        public void GetOutgoingFriends(Action<Friends> callback)
        {
            this.GetOutgoingFriends(null as GetPendingFollowFriendsCommand, callback);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="command"></param>
        /// <param name="callback"></param>
        public void GetOutgoingFriends(GetPendingFollowFriendsCommand command, Action<Friends> callback)
        {
            this.GetResultText(TwitterApiUrl.Version1_1.Friends.GetOutgoingUrl, command
                , json => callback(new Friends(json)));
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sourceID"></param>
        /// <param name="targetID"></param>
        /// <param name="callback"></param>
        public void ShowFriendships(Int64 sourceID, Int64 targetID, Action<Relationship> callback)
        {
            var cm = new ShowFriendshipsCommand();
            cm.SourceID = sourceID;
            cm.TargetID = targetID;
            this.ShowFriendships(cm, callback);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sourceScreenName"></param>
        /// <param name="targetScreenName"></param>
        /// <param name="callback"></param>
        public void ShowFriendships(String sourceScreenName, String targetScreenName, Action<Relationship> callback)
        {
            var cm = new ShowFriendshipsCommand();
            cm.SourceScreenName = sourceScreenName;
            cm.TargetScreenName = targetScreenName;
            this.ShowFriendships(cm, callback);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="command"></param>
        /// <param name="callback"></param>
        public void ShowFriendships(ShowFriendshipsCommand command, Action<Relationship> callback)
        {
            this.GetResultText(TwitterApiUrl.Version1_1.Friends.ShowUrl, command
                , json => callback(new Relationship(json)));
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="userID"></param>
        /// <param name="callback"></param>
        public void DestroyFriendship(Int64 userID, Action<User> callback)
        {
            var cm = new DestroyFriendshipCommand();
            cm.UserID = userID;
            this.DestroyFriendship(cm, callback);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="screenName"></param>
        /// <param name="callback"></param>
        public void DestroyFriendship(String screenName, Action<User> callback)
        {
            var cm = new DestroyFriendshipCommand();
            cm.ScreenName = screenName;
            this.DestroyFriendship(cm, callback);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="command"></param>
        /// <param name="callback"></param>
        public void DestroyFriendship(DestroyFriendshipCommand command, Action<User> callback)
        {
            this.GetResultText(HttpMethodName.Post, TwitterApiUrl.Version1_1.Friends.DestroyUrl, command
                , json => callback(new User(json)));
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="userID"></param>
        /// <param name="callback"></param>
        public void CreateFriendship(Int64 userID, Action<User> callback)
        {
            var cm = new CreateFriendshipCommand();
            cm.UserID = userID;
            this.CreateFriendship(cm, callback);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="screenName"></param>
        /// <param name="callback"></param>
        public void CreateFriendship(String screenName, Action<User> callback)
        {
            var cm = new CreateFriendshipCommand();
            cm.ScreenName = screenName;
            this.CreateFriendship(cm, callback);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="command"></param>
        /// <param name="callback"></param>
        public void CreateFriendship(CreateFriendshipCommand command, Action<User> callback)
        {
            this.GetResultText(HttpMethodName.Post, TwitterApiUrl.Version1_1.Friends.CreateUrl, command
                , json => callback(new User(json)));
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="command"></param>
        /// <param name="callback"></param>
        public void UpdateFriendship(UpdateFriendshipCommand command, Action<Relationship> callback)
        {
            this.GetResultText(HttpMethodName.Post, TwitterApiUrl.Version1_1.Friends.UpdateUrl, command
                , json => callback(new Relationship(json)));
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="callback"></param>
        public void GetNoRetweetIDs(Action<IEnumerable<Int64>> callback)
        {
            this.GetNoRetweetIDs(null, callback);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="command"></param>
        /// <param name="callback"></param>
        public void GetNoRetweetIDs(GetNoRetweetIDsCommand command, Action<IEnumerable<Int64>> callback)
        {
            this.GetResultText(HttpMethodName.Get, TwitterApiUrl.Version1_1.Friends.GetNoRetweetIDsUrl, command
                , json => callback(MakeInt64Array(json)));
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="jsonText"></param>
        /// <returns></returns>
        private IEnumerable<Int64> MakeInt64Array(String jsonText)
        {
            List<Int64> result = new List<Int64>();
            var cc = JsonConvert.DeserializeObject(jsonText) as JContainer;
            if (cc != null)
            {
                foreach (var i in cc)
                {
                    result.Add(Convert.ToInt64(i.ToString()));
                }
            }
            return result;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="uidValues"></param>
        /// <param name="callback"></param>
        public void LookupFriendships(Int64[] uidValues, Action<FriendshipCollection> callback)
        {
            StringBuilder sb = new StringBuilder(256);
            for (int i = 0; i < uidValues.Length; i++)
            {
                sb.Append(uidValues[i]);
                if (i < uidValues.Length - 1)
                {
                    sb.Append(",");
                }
            }
            var cm = new LookupFriendshipsCommand();
            cm.UserID = sb.ToString();
            this.LookupFriendships(cm, callback);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="nameValues"></param>
        /// <param name="callback"></param>
        public void LookupFriendships(String[] nameValues, Action<FriendshipCollection> callback)
        {
            StringBuilder sb = new StringBuilder(256);
            for (int i = 0; i < nameValues.Length; i++)
            {
                sb.Append(nameValues[i]);
                if (i < nameValues.Length - 1)
                {
                    sb.Append(",");
                }
            }
            var cm = new LookupFriendshipsCommand();
            cm.ScreenName = sb.ToString();
            this.LookupFriendships(cm, callback);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="command"></param>
        /// <param name="callback"></param>
        public void LookupFriendships(LookupFriendshipsCommand command, Action<FriendshipCollection> callback)
        {
            this.GetResultText(TwitterApiUrl.Version1_1.Friends.GetLookupUrl, command
                , json => callback(new FriendshipCollection(json)));
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="callback"></param>
        public void GetFriendsList(Action<FriendsUser> callback)
        {
            GetFriendsList(null as GetFriendsUserCommand, callback);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="command"></param>
        /// <param name="callback"></param>
        public void GetFriendsList(GetFriendsUserCommand command, Action<FriendsUser> callback)
        {
            this.GetResultText(TwitterApiUrl.Version1_1.Friends.GetFriendsListUrl, command
                , json => callback(new FriendsUser(json)));
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="callback"></param>
        public void GetFollowerList(Action<FriendsUser> callback)
        {
            GetFollowerList(null as GetFriendsUserCommand, callback);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="command"></param>
        /// <param name="callback"></param>
        public void GetFollowerList(GetFriendsUserCommand command, Action<FriendsUser> callback)
        {
            this.GetResultText(TwitterApiUrl.Version1_1.Friends.GetFollowerListUrl, command
                , json => callback(new FriendsUser(json)));
        }
    }
}
